package com.ruoyi.web.asyserver;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.business.domain.ShopCard;
import com.ruoyi.business.domain.ShopOrder;
import com.ruoyi.business.service.impl.ShopCardServiceImpl;
import com.ruoyi.business.service.impl.ShopOrderServiceImpl;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.utils.SnowIdUtils;
import com.ruoyi.web.utils.CommonUtil;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

import static com.ruoyi.web.bankCard.BankCardController.generateOrderNo;
import static org.apache.xmlbeans.impl.xsd2inst.SampleXmlUtil.WORDS;

@Slf4j
@Service
public class AsyncService {


    @Value("${wxpay.appid}")
    private String appId;
    @Value("${wxpay.appSecret}")
    private String appSecret;
    @Value("${wxpay.mchSerialNo}")
    private String mchSerialNo;
    @Value("${wxpay.apiKey3}")
    private String apiKey3;
    @Value("${wxpay.apiKey2}")
    private String apiKey2;
    @Value("${wxpay.keyPath}")
    private String keyPath;
    @Value("${wxpay.domain}")
    private String domain;
    @Value("${wxpay.certPath}")
    private String certPath;
    @Value("${wxpay.certP12Path}")
    private String certP12Path;
    @Value("${wxpay.mchId}")
    private String mchId;

    @Autowired
    private ShopCardServiceImpl cardService;

    @Autowired
    private ShopOrderServiceImpl orderService;

    @Autowired
    private RedisTemplate redisTemplate;


    @Async
    public void returnMoneyPay(ShopOrder order, String orderId) throws Exception {
        log.info("异步方法开始执行退款操作：" + Thread.currentThread().getName());
        try {
            Thread.sleep(5000);  // 模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //走退款流程
        // 商家内部的退款单号
        WechatPayHttpClientBuilder builder = getWechatPayHttpClientBuilder();

        CloseableHttpClient httpClient = builder.build();
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("out_trade_no", orderId);
        rootNode.put("out_refund_no", order.getTransactionId());
        rootNode.put("notify_url", domain + "/returnPay");
        rootNode.putObject("amount")
                .put("refund", order.getOrderAmount().multiply(new BigDecimal(100)).intValue())
                .put("total", order.getOrderAmount().multiply(new BigDecimal(100)).intValue())
                .put("currency", "CNY");
        objectMapper.writeValue(bos, rootNode);

        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        log.info("+++++++++++++++++++++++++++++++++发起退款+++++++++++++++++++++++++++++");
        log.info("+++++++++++++++++++++++++++++++++" + bos.toString("UTF-8") + "+++++++++++++++++++++++++++++");
        CloseableHttpResponse response2 = httpClient.execute(httpPost);
        String responseBody = EntityUtils.toString(response2.getEntity(), "UTF-8");
        Map<String, Object> responseMap = objectMapper.readValue(responseBody, Map.class);
        //返回退款结果
        log.info("+++++++++++++++++++++++++++++++" + JSON.toJSONString(responseMap) + "++++++++++++++++++++++++++++++++++++");

        System.out.println("异步方法执行完成：" + Thread.currentThread().getName());
    }


    public String redPackets(Map<String, String> params) throws Exception {
        // Step 3: 转换为XML格式
        String requestXml = mapToXml(params);

        // Step 4: 发送请求
        String response = sendHttpsPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", requestXml, mchId, certP12Path);
        log.info(response);

        return response;
    }


    private WechatPayHttpClientBuilder getWechatPayHttpClientBuilder() throws Exception {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                new FileInputStream(keyPath));

        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();

        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(mchId);
// ... 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

        X509Certificate certificate = verifier.getValidCertificate();
        List<X509Certificate> certificates = new ArrayList<>();
        certificates.add(certificate);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, CommonUtil.getSerialNumber(mchSerialNo, certPath), merchantPrivateKey)
                .withWechatPay(certificates);
        // ... 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

        // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签
        return builder;
    }


    // 转换 Map 为 XML
    private static String mapToXml(Map<String, String> params) {
        // 使用 TreeMap 对参数进行排序
        Map<String, String> sortedParams = new TreeMap<>(params);

        StringBuilder sb = new StringBuilder();
        sb.append("<xml>");

        // 遍历排序后的参数，并构建 XML 字符串
        sortedParams.forEach((key, value) -> sb.append("<").append(key).append(">")
                .append("<![CDATA[").append(value).append("]]>")
                .append("</").append(key).append(">"));

        sb.append("</xml>");
        return sb.toString();
    }

    // 发送 HTTPS POST 请求
    private static String sendHttpsPost(String url, String xmlData, String mchId, String certPath) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        File file = new File(certPath);
        try (FileInputStream fis = new FileInputStream(file)) {
            keyStore.load(fis, mchId.toCharArray());
        }

        SSLContext sslContext = SSLContextBuilder.create()
                .loadKeyMaterial(keyStore, mchId.toCharArray())
                .build();

        try (CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLContext(sslContext)
                .build()) {
            HttpPost post = new HttpPost(url);
            post.setEntity(new StringEntity(xmlData, "UTF-8"));
            post.addHeader("Connection", "keep-alive");
            post.addHeader("Accept", "*/*");
            post.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            post.addHeader("Host", "api.mch.weixin.qq.com");
            post.addHeader("X-Requested-With", "XMLHttpRequest");
            post.addHeader("Cache-Control", "max-age=0");
            post.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");


            try (CloseableHttpResponse response = httpClient.execute(post)) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        }
    }


    //发放现金红包
    @Async
    public void sendRedCard(Long orderId, BigDecimal price, String openId, HttpServletRequest request) throws Exception {
        ShopOrder shopOrder  = new ShopOrder();
        Boolean flag = null;
        Map<String, String> paramMap = new HashMap<String, String>();
        //随机字符串
        paramMap.put("nonce_str", generateUniqueWordString());
        //商户订单号
        paramMap.put("mch_billno", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + (int) ((Math.random() * 9 + 1) * 1000));
        //商户号
        paramMap.put("mch_id", mchId);
        //公众账号appid
        paramMap.put("wxappid", appId);
        //商户名称
        paramMap.put("send_name", "臻享出行");
        //用户openid
        paramMap.put("re_openid", openId);
        //付款金额
        paramMap.put("total_amount", price.multiply(new BigDecimal(100)).intValue() + "");
        //红包发放总人数
        paramMap.put("total_num", "1");
        //红包祝福语
        paramMap.put("wishing", "恭喜您获得红包");
        //Ip地址
        paramMap.put("client_ip", getClientIp(request));
        //活动名称
        paramMap.put("act_name", "现金返现");
        //备注
        paramMap.put("remark", "恭喜您获得红包");
        //场景id 发放红包使用场景，红包金额大于200或者小于1元时必传，以外非必须。
        // paramMap.put("scene_id","PRODUCT_2");

        //paramMap.put("risk_info",generateRiskInfo(new Date().getTime()+"","17356263105",generateUniqueWordString(),"1.0"));

        // Step 2: 生成签名
        String sign = generateSign(paramMap, apiKey2);
        paramMap.put("sign", sign);
        //发放红包
        // Step 3: 转换为XML格式
        String requestXml = mapToXml(paramMap);
        log.info("红包请求参数==>{}", requestXml);

        // Step 4: 发送请求
        String responseXml = sendHttpsPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", requestXml, mchId, certP12Path);
        log.info(responseXml);


        log.info("红包请求返回参数==>{}", responseXml);

        try {
            Map<String, String> parsedResult = parseResponse(responseXml);
            System.out.println("解析结果: " + parsedResult);

            // 示例：根据解析结果处理业务逻辑
            if ("SUCCESS".equals(parsedResult.get("result_code"))) {
                log.info("调用成功，发送红包ID: " + parsedResult.get("send_listid"));
                log.info("红包发放成功==>{}");
                shopOrder.setOrderAmount(price);
            } else {
                log.info("调用失败，错误信息: " + parsedResult.get("return_msg"));
                shopOrder.setStayAmount(price);
                shopOrder.setOrderAmount(BigDecimal.ZERO);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        shopOrder.setOrderId(orderId);
        orderService.updateById(shopOrder);

    }

    @Async
    public Boolean sendRedCard2(Long orderId, BigDecimal price, String openId, HttpServletRequest request) throws Exception {
        Boolean flag = null;
        Map<String, String> paramMap = new HashMap<String, String>();
        //随机字符串
        paramMap.put("nonce_str", generateUniqueWordString());
        //商户订单号
        paramMap.put("mch_billno", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + (int) ((Math.random() * 9 + 1) * 1000));
        //商户号
        paramMap.put("mch_id", mchId);
        //公众账号appid
        paramMap.put("wxappid", appId);
        //商户名称
        paramMap.put("send_name", "臻享出行");
        //用户openid
        paramMap.put("re_openid", openId);
        //付款金额
        paramMap.put("total_amount", price.multiply(new BigDecimal(100)).intValue() + "");
        //红包发放总人数
        paramMap.put("total_num", "1");
        //红包祝福语
        paramMap.put("wishing", "恭喜您获得红包");
        //Ip地址
        paramMap.put("client_ip", getClientIp(request));
        //活动名称
        paramMap.put("act_name", "现金返现");
        //备注
        paramMap.put("remark", "恭喜您获得红包");
        //场景id 发放红包使用场景，红包金额大于200或者小于1元时必传，以外非必须。
        // paramMap.put("scene_id","PRODUCT_2");

        //paramMap.put("risk_info",generateRiskInfo(new Date().getTime()+"","17356263105",generateUniqueWordString(),"1.0"));

        // Step 2: 生成签名
        String sign = generateSign(paramMap, apiKey2);
        paramMap.put("sign", sign);
        //发放红包
        // Step 3: 转换为XML格式
        String requestXml = mapToXml(paramMap);
        log.info("红包请求参数==>{}", requestXml);

        // Step 4: 发送请求
        String responseXml = sendHttpsPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", requestXml, mchId, certP12Path);
        log.info(responseXml);


        log.info("红包请求返回参数==>{}", responseXml);

        try {
            Map<String, String> parsedResult = parseResponse(responseXml);
            System.out.println("解析结果: " + parsedResult);

            // 示例：根据解析结果处理业务逻辑
            if ("SUCCESS".equals(parsedResult.get("result_code"))) {
                log.info("调用成功，发送红包ID: " + parsedResult.get("send_listid"));
                log.info("红包发放成功==>{}");
                flag = true;

            } else {
                log.info("调用失败，错误信息: " + parsedResult.get("return_msg"));
                flag = false;

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (flag == null) {
                flag = false;

            }
        }

        return  flag;


    }


    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        // 如果通过代理获取到了多个IP地址，取第一个非未知的IP
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr(); // 直接获取请求者的 IP 地址
        }

        // 在某些情况下，通过代理会返回多个 IP 地址，取第一个有效的 IP 地址
        if (ip != null && ip.length() > 15) {
            int idx = ip.indexOf(',');
            if (idx > 0) {
                ip = ip.substring(0, idx);
            }
        }

        return ip;
    }


    //公众号发放卡卷
    @Async
    public void sendCard(String openid, Long orderId) throws Exception {
        ShopOrder shopOrder = new ShopOrder();
        log.info("发放卡卷===>{}", orderId);
        log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        try {
            Thread.sleep(2000);  // 模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        //获取本月最新的可发卡卷
        String time = DateUtil.format(new Date(), "yyyy-MM");
        ShopCard shopCard = cardService.getOne(new QueryWrapper<ShopCard>().lambda().eq(ShopCard::getMonth, time).eq(ShopCard::getDelFlag, 0).orderByDesc(BaseEntity::getCreateTime).last("limit 1"));
        List<String> cardList = new ArrayList<>();
        CloseableHttpClient httpClient = getWechatPayHttpClientBuilder2().build();
        String sendCouponUrl = String.format("https://api.mch.weixin.qq.com/v3/marketing/favor/users/%s/coupons", openid);
        HashMap<String, String> paraMap = new HashMap<>();
        paraMap.put("stock_id", shopCard.getStockId());
        paraMap.put("out_request_no", generateOrderNo(mchId));
        paraMap.put("appid", appId);
        paraMap.put("stock_creator_mchid", mchId);
        log.info("request url=" + sendCouponUrl);
        log.info("request params=" + com.alibaba.fastjson2.JSONObject.toJSONString(paraMap));

        HttpPost httpPost = new HttpPost(sendCouponUrl);
        StringEntity reqEntity = new StringEntity(com.alibaba.fastjson2.JSONObject.toJSONString(paraMap),
                ContentType.create("application/json", "utf-8"));
        httpPost.setEntity(reqEntity);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-Type", "application/json");

        CloseableHttpResponse response = null;
        try {
            log.info("微信发券接口地址：" + sendCouponUrl + ",入参：" + com.alibaba.fastjson2.JSONObject.toJSONString(httpPost));
            response = httpClient.execute(httpPost);
            log.info("微信发券接口返回结果code：" + response.getStatusLine().getStatusCode() + ",内容：" + EntityUtils.toString(response.getEntity()));
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(response.getEntity());
                log.info("response=" + result);
            }
        } catch (Exception e) {
            log.error("excepiton:" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        shopOrder.setOrderId(orderId);
        String string = EntityUtils.toString(response.getEntity());
        JSONObject jsonObject = JSONObject.parseObject(string);
        if(jsonObject.getString("coupon_id")!=null && jsonObject.getString("coupon_id").length()>0){
            cardList.add("[" + shopCard.getId() + "]已发放");
            shopOrder.setRedCard(shopCard.getId().toString());
        }else {
            shopOrder.setRedCard("-1");
        }



        shopOrder.setCouponId(jsonObject.getString("coupon_id"));
        orderService.updateById(shopOrder);
    }

    //补发卡卷
    public Boolean sendCard2(String openid, ShopCard shopCard) throws Exception {
        Boolean flag = null;
        log.info("+++++++++++++++++++++++++++++开始补发卡卷+++++++++++++++++++++++++++++++++++++++++++++++++");
        try {
            Thread.sleep(2000);  // 模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        CloseableHttpClient httpClient = getWechatPayHttpClientBuilder2().build();
        String sendCouponUrl = String.format("https://api.mch.weixin.qq.com/v3/marketing/favor/users/%s/coupons", openid);
        HashMap<String, String> paraMap = new HashMap<>();
        paraMap.put("stock_id", shopCard.getStockId());
        paraMap.put("out_request_no", generateOrderNo(mchId));
        paraMap.put("appid", appId);
        paraMap.put("stock_creator_mchid", mchId);
        log.info("request url=" + sendCouponUrl);
        log.info("request params=" + com.alibaba.fastjson2.JSONObject.toJSONString(paraMap));

        HttpPost httpPost = new HttpPost(sendCouponUrl);
        StringEntity reqEntity = new StringEntity(com.alibaba.fastjson2.JSONObject.toJSONString(paraMap),
                ContentType.create("application/json", "utf-8"));
        httpPost.setEntity(reqEntity);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-Type", "application/json");

        CloseableHttpResponse response = null;
        try {
            log.info("微信发券接口地址：" + sendCouponUrl + ",入参：" + com.alibaba.fastjson2.JSONObject.toJSONString(httpPost));
            response = httpClient.execute(httpPost);
            log.info("微信发券接口返回结果code：" + response.getStatusLine().getStatusCode() + ",内容：" + EntityUtils.toString(response.getEntity()));
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(response.getEntity());
                log.info("response=" + result);
                flag = true;
                return flag;
            } else {
                flag = false;
                return flag;
            }
        } catch (Exception e) {
            log.error("excepiton:" + e.getMessage());
            e.printStackTrace();
        } finally {
            if (flag == null) {
                return false;
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        ShopOrder shopOrder = new ShopOrder();
        shopOrder.setOpenid(openid);
        shopOrder.setRedCard(shopCard.getId().toString());
        String string = EntityUtils.toString(response.getEntity());
        JSONObject jsonObject = JSONObject.parseObject(string);
        shopOrder.setRedCard("6");
        shopOrder.setCouponId(jsonObject.getString("coupon_id"));
        orderService.updateById(shopOrder);
        return false;
    }

    private static String generateSign(Map<String, String> params, String apiKey) throws Exception {
        // 1. 参数排序
        Map<String, String> sortedParams = new TreeMap<>(params);

        // 2. 拼接字符串
        StringBuilder stringA = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            // 忽略空值
            if (value != null && !value.isEmpty()) {
                stringA.append(key).append("=").append(value).append("&");
            }
        }
        // 拼接API密钥
        stringA.append("key=").append(apiKey);

        // 3. MD5加密
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(stringA.toString().getBytes(StandardCharsets.UTF_8));
        StringBuilder sign = new StringBuilder();
        for (byte b : digest) {
            sign.append(String.format("%02x", b));
        }
        // 转为大写
        return sign.toString().toUpperCase();
    }

    /**
     * 解析微信红包接口的 XML 响应
     *
     * @param responseXml 接口返回的 XML 字符串
     * @return 解析结果的 Map
     * @throws Exception 如果解析失败
     */
    public static Map<String, String> parseResponse(String responseXml) throws Exception {
        Map<String, String> resultMap = new HashMap<>();

        // 将 XML 字符串转换为 InputStream
        ByteArrayInputStream inputStream = new ByteArrayInputStream(responseXml.getBytes("UTF-8"));

        // 使用 DocumentBuilder 解析 XML
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(inputStream);

        // 获取 XML 根节点
        NodeList nodes = document.getDocumentElement().getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            if (nodes.item(i).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
                String nodeName = nodes.item(i).getNodeName();
                String nodeValue = nodes.item(i).getTextContent();
                resultMap.put(nodeName, nodeValue);
            }
        }
        return resultMap;
    }

    private WechatPayHttpClientBuilder getWechatPayHttpClientBuilder2() throws Exception {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
                new FileInputStream(keyPath));

        // 获取证书管理器实例
        // 初始化 CertificatesManager
        CertificatesManager certificatesManager = CertificatesManager.getInstance();

        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(mchId);
        // 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

        X509Certificate certificate = verifier.getValidCertificate();
        List<X509Certificate> certificates = new ArrayList<>();
        certificates.add(certificate);

        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, CommonUtil.getSerialNumber(mchSerialNo, certPath), merchantPrivateKey)
                .withWechatPay(certificates);
        // ... 接下来，你仍然可以通过builder设置各种参数，来配置你的HttpClient

        // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签
        return builder;
    }


    public static String generateUniqueWordString() {
        String word = WORDS[ThreadLocalRandom.current().nextInt(WORDS.length)];
        String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 12);
        return word + uuidPart;
    }

    //----------------------------------------------------------------------------------------------------------




}
